import {
  Body,
  Controller,
  Del,
  Get,
  Inject,
  Param,
  Post,
  Put,
  Query
} from '@midwayjs/core'
import { Context } from '@midwayjs/koa'
import {
  ApiBearerAuth,
  ApiOperation,
  ApiResponse,
  ApiTags
} from '@midwayjs/swagger'
import { Validate } from '@midwayjs/validate'
import { ExcelService } from '@ttou/midway-excel'

import { CACHE_KEYS } from '@/constant'
import { DeleteDTO } from '@/dto'
import { CacheMiddleware } from '@/middleware'

import {
  CreateDictDataDTO,
  CreateDictTypeDTO,
  FindDictDataPageDTO,
  FindDictTypePageDTO,
  UpdateDictDataDTO,
  UpdateDictTypeDTO
} from './dict.dto'
import {
  DictDataExportSerialize,
  DictTypeExportSerialize
} from './dict.serialize'
import { DictService } from './dict.service'
import {
  GetDictDataListVO,
  GetDictDataPageVO,
  GetDictTypePageVO,
  GetDictTypeVO
} from './dict.vo'

@ApiBearerAuth()
@ApiTags('系统/字典接口')
@Controller('/system/dict')
export class DictController {
  @Inject()
  ctx: Context

  @Inject()
  dictService: DictService

  @Inject()
  excelService: ExcelService

  @ApiOperation({ summary: '获取字典类型分页' })
  @ApiResponse({ status: 200, type: GetDictTypePageVO })
  @Post('/type/page')
  @Validate()
  async getDictTypePage(@Body() dto: FindDictTypePageDTO) {
    return await this.dictService.handleFindDictTypePage(dto)
  }

  @ApiOperation({ summary: '新建字典类型' })
  @Post('/type/create')
  @Validate()
  async createDictType(@Body() dto: CreateDictTypeDTO) {
    await this.dictService.handleCreateDictType(dto)
  }

  @ApiOperation({ summary: '更新字典类型' })
  @Put('/type/update/:id')
  @Validate()
  async updateDictType(
    @Param('id') id: string,
    @Body() dto: UpdateDictTypeDTO
  ) {
    await this.dictService.handleUpdateDictType(id, dto)
  }

  @ApiOperation({ summary: '删除字典类型' })
  @Del('/type/delete')
  @Validate()
  async deleteDictType(@Body() dto: DeleteDTO) {
    await this.dictService.handleDeleteDictType(dto)
  }

  @ApiOperation({ summary: '获取字典类型' })
  @ApiResponse({ status: 200, type: GetDictTypeVO })
  @Get('/type')
  async getDictType(@Query('id') id: string) {
    return await this.dictService.handleFindDictType(id)
  }

  @ApiOperation({ summary: '导出字典类型分页' })
  @Post('/type/export')
  @Validate()
  async exportDictTypePage(@Body() dto: FindDictTypePageDTO) {
    const { list } = await this.dictService.handleFindDictTypePage(dto)

    const result = await this.excelService.handleExport({
      sheetName: '字典类型',
      filename: '字典类型报表',
      Cls: DictTypeExportSerialize,
      data: list
    })

    this.ctx.set(result.headers)
    this.ctx.body = result.body
  }

  @ApiOperation({ summary: '获取字典数据分页' })
  @ApiResponse({ status: 200, type: GetDictDataPageVO })
  @Post('/data/page')
  @Validate()
  async getDictDataPage(@Body() dto: FindDictDataPageDTO) {
    return await this.dictService.handleFindDictDataPage(dto)
  }

  @ApiOperation({ summary: '获取字典数据列表' })
  @ApiResponse({ status: 200, type: GetDictDataListVO })
  @Get('/data/list/:dictType', {
    middleware: [
      CacheMiddleware({
        key: ctx => `${CACHE_KEYS.SYS_DICT_KEY}${ctx.params.dictType}`,
        ttl: 15 * 1000
      })
    ]
  })
  async getDictDataList(@Param('dictType') dictType: string) {
    return await this.dictService.handleFindDictDataList(dictType)
  }

  @ApiOperation({ summary: '新建字典数据' })
  @Post('/data/create')
  @Validate()
  async createDictData(@Body() dto: CreateDictDataDTO) {
    await this.dictService.handleCreateDictData(dto)
  }

  @ApiOperation({ summary: '更新字典数据' })
  @Put('/data/update/:id')
  @Validate()
  async updateDictData(
    @Param('id') id: string,
    @Body() dto: UpdateDictDataDTO
  ) {
    await this.dictService.handleUpdateDictData(id, dto)
  }

  @ApiOperation({ summary: '删除字典数据' })
  @Del('/data/delete')
  @Validate()
  async deleteDictData(@Body() dto: DeleteDTO) {
    await this.dictService.handleDeleteDictData(dto)
  }

  @ApiOperation({ summary: '导出字典数据分页' })
  @Post('/data/export')
  @Validate()
  async exportDictDataPage(@Body() dto: FindDictDataPageDTO) {
    const { list } = await this.dictService.handleFindDictDataPage(dto)

    const result = await this.excelService.handleExport({
      sheetName: '字典数据',
      filename: '字典数据报表',
      Cls: DictDataExportSerialize,
      data: list
    })

    this.ctx.set(result.headers)
    this.ctx.body = result.body
  }
}
